package com.pentajock.docdb.images;

/*
 * Liscense: 	GPL http://www.gnu.org/copyleft/gpl.html
 * By: 		A. Tres Finocchiaro
 * Date:	2007
 * Java:	6.0SE
 */

import com.pentajock.docdb.Main;
import com.pentajock.docdb.database.DBController;
import com.pentajock.docdb.types.User;
import com.pentajock.docdb.types.Document;
import com.pentajock.docdb.types.WeightedDocument;
import com.pentajock.docdb.utils.Utils;
import java.io.*;
import java.awt.*;
import java.net.URI;
import javax.swing.*;
import javax.imageio.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.*;
//import java.util.ArrayList;
//import java.lang.ClassLoader;
import java.net.URISyntaxException;
import java.util.ArrayList;
import javax.swing.UIManager.*;
//import java.net.URISyntaxException;

public enum DBImages {
	// WINDOW ICONS
	LOGIN_WINDOW		("icon_window_login.png"),
	//"window-login"
	
	CLIENT_WINDOW		("icon_window_client.png"),
	//"window-main"
	
	ADMIN_WINDOW		("icon_window_admin.png"),
	//"window-admin"
	//PDF_WINDOW		("icon_window_acrobat.png"),
	//"window-
	
	CUSTOM_WINDOW		("icon_window_custom.png"),
	//"window-custom"
	
	// DOCUMENT ACTIONS
	DOC_ASSIGNED_BUTTON	("icon_doc_assigned.png"),
	//"document-assigned"
	
	DOC_RENAME_BUTTON	("icon_doc_rename.png"),
	//"document-rename"
	
	DOC_LIST_BUTTON		("icon_doc_list.png"),
	//"document-list"
	
	DOC_LINK_BUTTON		("icon_doc_link.png"),
	//"document-send"
	//"mail-send"
	
	DOC_SEND_BUTTON		("icon_doc_send.png"),
	//"document-new"
	
	DOC_ADD_BUTTON		("icon_doc_add.png"),
	//"document-add-notes"
	
	DOC_ADD_NOTES_BUTTON	("icon_doc_add_notes.png"),
	//"document-edit"
	
	DOC_EDIT_BUTTON		("icon_doc_edit.png"),
	//"document-open"
	
	DOC_OPEN_BUTTON		("icon_doc_open.png"),
	//"document-copy"
	
	DOC_DESKTOP_BUTTON	("icon_doc_desktop.png"),
	// COMMON ACTIONS
	
	ADD_BUTTON		("icon_add.png"),
	//"list-add"
	
	REMOVE_BUTTON		("icon_remove.png"),
	//"list-remove"
	
	
	EDIT_BUTTON		("icon_edit.png"),
	//"list-edit"
	//"document-edit"
	//"document-open"
	
	
	SEARCH_BUTTON		("icon_search.png"),
	//"system-search"
	//"list-search"
	
	
	REVERT_BUTTON		("icon_revert.png"),
	//"document-revert"
	
	SAVE_BUTTON		("icon_save.png"),
	//"document-save"
	
	PRINT_BUTTON		("icon_print.png"),
	//"document-print"
	
	EXIT_BUTTON		("icon_exit.png"),
	//"application-exit"
	
	APPLY_BUTTON		("icon_apply.png"),
	//"dialog-ok"
	//"document-save"
	
	//CLOSE_BUTTON		(""),
	//"dialog-close"
	
	LOGOUT_BUTTON		("icon_logout.png"),
	//"system-log-out"
	
	
	ADMIN_BUTTON		("icon_admin.png"),
	//"security-high"
	
	// COMMON ICONS
        // WAND = CATGORY ENABLED/DISABLED CAN BE CHANGED TO OK ICON
	WAND_ICON		("icon_wand.png"),
	// USE OK ICON
	
	RESIZE_ICON		("icon_resizer.gif"),
	//"view-resize"
	COLOR_ICON		("icon_color.png"),
	//"dialog-color"
	STYLE_ICON		("icon_style.png"),
	///"preferences-desktop-theme"
	
	SHORTCUT_ICON		("icon_shortcut.png"),
	//"emblem-symbolic-link"
	//UNLOCK_ICON		("icon_unlock.png"),
	CLOCK_ICON		("icon_clock.png"),
	//"emblem-clock"
	
	CLOCK_EXCLAIM_ICON	("icon_clock_exclaim.png"),
	
	KEY_ICON		("icon_key.png"),
	//"dialog-password"
	
	PANEL_ICON		("icon_panel.png"),
	//"view-panel"
	
	BULB_ICON		("icon_bulb.png"),
	//"help-about"
	
	BUG_ICON		("icon_bug.png"),
	//"dialog-bug"
	
	CATEGORY_ICON		("icon_category.png"),
	//"x-office-category"
	
	SERVER_ICON		("icon_server.png"),
	// MIMETYPE ICONS
	WORD_ICON		("icon_mime_word.png"),
	//"x-office-document"
	EXCEL_ICON		("icon_mime_excel.png"),
	//"x-office-spreadsheet"
	POWERPOINT_ICON		("icon_mime_powerpoint.png"),
	//"x-office-presentation"
	ACROBAT_ICON		("icon_mime_acrobat.png"),
	//"x-office-portable"
	INFOPATH_ICON		("icon_mime_infopath.png"),
	//"x-office-form"
	VISIO_ICON		("icon_mime_visio.png"),
	//"x-office-draw"
	OFFICE_ICON		("icon_mime_office.png"),
	//"applications-office"
	//"x-office-microsoft"
	GENERIC_ICON		("icon_mime_generic.png"),
	//"text-x-generic"
	// USER/GROUP ACTIONS
        // CAN BE REPLACED WITH GENERIC ADD/REMOVES
	USER_ADD_BUTTON		("icon_user_add.png"),
	USER_EDIT_BUTTON	("icon_user_edit.png"),
	USER_REMOVE_BUTTON	("icon_user_remove.png"),
	GROUP_ADD_BUTTON	("icon_group_add.png"),
	GROUP_EDIT_BUTTON	("icon_group_edit.png"),
	GROUP_REMOVE_BUTTON	("icon_group_remove.png"),
	// USER/GROUP TYPES
	
	/*
	 * STATUS ICONS
	 */
	//"user-online"
	USER_ICON		("icon_user.png"),
	//"group-online"
	GROUP_ICON		("icon_group.png"),
	
	//"security-medium"
	USER_SUPER_ICON		("icon_user_super.png"),
	//"security-high"
	USER_ADMIN_ICON		("icon_user_admin.png"),
	// GUI ICONS
	
	/*
	 * Theme mimetypes
	 */
	//"desktop-theme-xp"
	GUI_XP_ICON		("icon_gui_xp.png"),
	//"desktop-theme-windows"
	GUI_WIN_ICON		("icon_gui_win.png"),
	//"desktop-theme-cde"
	GUI_CDE_ICON		("icon_gui_cde.png"),
	//"desktop-theme-gtk"
	GUI_GTK_ICON		("icon_gui_gtk.png"),
	//"desktop-theme-metal"
	GUI_METAL_ICON		("icon_gui_metal.png"),
	//"desktop-theme-osx"
	GUI_OSX_ICON		("icon_gui_osx.png"),
	//"desktop-theme-default"
	GUI_DEFAULT_ICON	("icon_gui_default.png"),
	// LANGUAGE
	//"preferences-desktop-locale"
	LANG_DEFAULT_ICON	("icon_lang_default.png");
	
	private BufferedImage img;
	private String path;
	private static class MimeType {
		public String extension;
		public String activeXCall;
		public Icon icon;
		public URI iconURI;
	}
	private static class Alert {
		public int documentID;
		public Icon icon;
	}

	private static java.util.List<Alert> alertCache;
	private static java.util.List<MimeType> mimeTypes;
	
	private static String DEFAULT_SIZE = "16x16";
	private static String DEFAULT_ICON_ROOT = "/usr/share/icons";
	
	DBImages(String path) {
		Main.printDebug("Loading: " + path + "... &");
		img = null;
                //path = "/com/pentajock/docdb/images/" + path;
		this.path = path;
		try {
			img = ImageIO.read(getClass().getResource(path));
			Main.printDebug("successful.");
		}
		catch(IllegalArgumentException ex) {
			Main.printStackTrace(ex, "Image file not found: " + path);
		}
		catch(IOException ex) {
			Main.printStackTrace(ex, "Error loading image file: " + path);
		}
	}
	
	public BufferedImage getImage() {
		return img;
	}
	
	/* Could just cast from ImageIcon to Icon, but this saves a step */
	public Icon getIcon() {
		return getImageIcon(); 
	}
	
	public URI getURI() {
		try {
			return new URI("file:" +path);
		}
		catch (URISyntaxException e) {
			return null;
		}
	}
	
	public ImageIcon getImageIcon() {
		if(img == null) {
			return null;
		}
		return new ImageIcon(img);
	}
	
	public Cursor getCursor() {
		if (img == null) {
			return null;
		}
		return Toolkit.getDefaultToolkit().createCustomCursor(img, (new Point(0, 0)), "CUSTOM_CURSOR");
	}
	
	/* Get mimetype icon for specified document/file/extension */
	public static Icon getMimeType(Object o) throws Exception {
		String extension;
		if (o instanceof File)
			extension = Utils.getExtension((File)o);
		if (o instanceof Document)
			extension = ((Document)o).getExtension();
		else if (o instanceof String)
			extension = Utils.getExtension((String)o);
		else 
			return GENERIC_ICON.getIcon();
		
		if (mimeTypes == null)
			buildMimeTypes();
		for (MimeType m : mimeTypes) {
			if (m.extension.equalsIgnoreCase(extension)) { 
				return m.icon; 
			}
			else if (extension.equalsIgnoreCase("xml")) {
				File f = null;
				if (o instanceof File)
					f = (File)o;
				if (o instanceof Document)
					f = ((Document)o).toFile();
				if (m.activeXCall.equalsIgnoreCase(Utils.getXMLActiveXCall(f))) 
					return m.icon;
			}
		}
		return GENERIC_ICON.getIcon();
	}
	
	/* Returns a URI for the appropriate object (for HTML dialogs / menus) */
	/**private static URI getURI(Object o) {
		String extension;
		if (o instanceof File)
			extension = Utils.getExtension((File)o);
		else if (o instanceof Document)
			extension = ((Document)o).getExtension();
		else if (o instanceof User) {
			if (((User)o).isAdmin())
				return USER_ADMIN_ICON.getURI();
			else if (((User)o).isSupervisor())
				return USER_SUPER_ICON.getURI();
			else
				return USER_ICON.getURI();
		}
		else 
			return GENERIC_ICON.getURI();
		
		if (mimeTypes == null)
			buildMimeTypes();
		for (MimeType m : mimeTypes) {
			if (m.extension.equalsIgnoreCase(extension)) { 
				return m.iconURI; 
			}
			else if (extension.equalsIgnoreCase("xml")) {
				File f = null;
				if (o instanceof File)
					f = (File)o;
				else if (o instanceof Document)
					f = ((Document)o).toFile();
				try {
					if (m.activeXCall.equalsIgnoreCase(Utils.getXMLActiveXCall(f))) 
					return m.iconURI;
				}
				catch (Exception e) {}
			}
		}
		return GENERIC_ICON.getURI();
	}**/

	public static Icon getMimeType(Object o, Color c) throws Exception {
		if (o instanceof WeightedDocument) {
			if (alertCache == null) alertCache = new ArrayList<DBImages.Alert>();
			WeightedDocument d = (WeightedDocument)o;
			if (Utils.daysDue(d) > 0 && d.getUpdateInterval() > 0) { // If positive, flag as overdue
				for (Alert a : alertCache)
					if (a.documentID == d.getDocumentID())
						return a.icon;
				
				Alert a = new Alert();
					a.documentID = d.getDocumentID();
					a.icon = getAttentionImage(getMimeType(d), c);
				alertCache.add(a);
				return a.icon;
			}
			else
				return getMimeType(d);
		}
		return GENERIC_ICON.getIcon();
	}
	
	/*
	 * Reset alert icons in the event of a color change
	 */
	public static void resetAlertIcons() {
		alertCache = null;
	}
	
	public static Icon getUserIcon(Object o) {
		if (!(o instanceof User) || o == null) return null;
		if (((User)o).isAdmin()) 
			return USER_ADMIN_ICON.getIcon();
		else if (((User)o).isSupervisor()) 
			return USER_SUPER_ICON.getIcon();
		else
			return USER_ICON.getIcon();
	}
	
	public static Icon getLanguageIcon(Object o) {
		try {
			if ((o instanceof String || o instanceof File) && o != null) {
				return new ImageIcon(ImageIO.read(new File("/com/pentajock/docdb/lang/images/" + Utils.getSubject(o) + ".png")));
			}
		}
		catch (Exception e) {
		}
		return LANG_DEFAULT_ICON.getIcon();
	}
	
	public static Icon getLookAndFeelIcon(Object o) {
		if (o instanceof LookAndFeelInfo && o != null) {
			LookAndFeelInfo p = (LookAndFeelInfo)o;
			String s = p.getName();
			if (s.toLowerCase().equals("metal"))
				return GUI_METAL_ICON.getIcon();
			else if (s.toLowerCase().startsWith("cde") || s.toLowerCase().startsWith("motif"))
				return GUI_CDE_ICON.getIcon();
			else if (s.toLowerCase().equals("windows") || s.toLowerCase().equals("windows xp"))
				return GUI_XP_ICON.getIcon();
			else if (s.toLowerCase().equals("windows classic"))
				return GUI_WIN_ICON.getIcon();
			else if (s.toLowerCase().startsWith("osx") || s.toLowerCase().startsWith("quaqua"))
				return GUI_OSX_ICON.getIcon();
			else if (s.toLowerCase().startsWith("gtk"))
				return GUI_GTK_ICON.getIcon();
			else if (p.getClassName() == null)
				return GUI_DEFAULT_ICON.getIcon();
			
			/* 
			 * Look for the icon in the 
			 * .themes/images/ folder matching 
			 * lookAndFeelInfo.getName
			 */
			else {
				try {
					return new ImageIcon(ImageIO.read(new File(".themes/images/" + s + ".png")));
				}
				catch (Exception e) {
					return GUI_WIN_ICON.getIcon();
				}
			}
		}
		return null;
	}
	
	public static BufferedImage getUserIconImage(Object o) {
		if (!(o instanceof User)) return null;
		if (((User)o).isAdmin()) 
			return USER_ADMIN_ICON.getImage();
		else if (((User)o).isSupervisor()) 
			return USER_SUPER_ICON.getImage();
		else
			return USER_ICON.getImage();
	}
	
	private static void buildMimeTypes() {
		mimeTypes = new ArrayList<MimeType>();
		for (String s : DBController.getExtensions()) {
			if (!s.equals("xml")) {	// xml files need to be handled separately.
				MimeType m = new MimeType();
				m.extension = s;
				m.activeXCall = DBController.getActiveXCall(s);
				if (m.activeXCall == null) {
					m.icon = GENERIC_ICON.getIcon();
					m.iconURI = GENERIC_ICON.getURI();
				}
				else if (m.activeXCall.equalsIgnoreCase("Word.Application"))  {
					m.icon = WORD_ICON.getIcon();
					m.iconURI = WORD_ICON.getURI();
				}
				else if (m.activeXCall.equalsIgnoreCase("Excel.Application")) {
					m.icon = EXCEL_ICON.getIcon();
					m.iconURI = EXCEL_ICON.getURI();
				}
				else if (m.activeXCall.equalsIgnoreCase("Visio.Application")) {
					m.icon = VISIO_ICON.getIcon();
					m.iconURI = VISIO_ICON.getURI();
				}
				else if (m.activeXCall.equalsIgnoreCase("Acrobat.Application")) {
					m.icon = ACROBAT_ICON.getIcon();
					m.iconURI = ACROBAT_ICON.getURI();
				}
				else if (m.activeXCall.equalsIgnoreCase("InfoPath.Application")) {
					m.icon = INFOPATH_ICON.getIcon();
					m.iconURI = INFOPATH_ICON.getURI();
				}
				else { 
					m.icon = GENERIC_ICON.getIcon();
					m.iconURI = GENERIC_ICON.getURI();
				}
				mimeTypes.add(m);
			}
		}
	}
	
	public static Icon getAttentionImage(Object o, Color c) {
		int w; int h;
		BufferedImage img;
		if (o instanceof Icon) {
			ImageIcon image = (ImageIcon)o;
			w = image.getIconWidth(); h = image.getIconHeight();
			img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
			img = img.createGraphics().getDeviceConfiguration().createCompatibleImage(w, h, img.TRANSLUCENT);
			Graphics2D g = img.createGraphics();
			g.setComposite(AlphaComposite.Src); g.drawImage(image.getImage(), 0, 0, null); g.dispose();
		}
		else if (o instanceof BufferedImage)
			img = (BufferedImage)o;
		else
			return null;
		
		w = img.getWidth(); h = img.getHeight();
		Font f = new Font("Times New Roman", Font.BOLD, 16);
		Graphics2D g = img.createGraphics();
		BufferedImage textImage = g.getDeviceConfiguration().createCompatibleImage(w, h, img.TRANSLUCENT);
		g = textImage.createGraphics();
		g.setComposite(AlphaComposite.Src); g.drawImage(img, 0, 0, w, h, null);	g.setFont(f); g.setPaint(c);
		g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
		TextLayout textLayout = new TextLayout("!", f, g.getFontRenderContext());
		Rectangle2D r = textLayout.getBounds();
		textLayout.draw(g, (float)(w/1.25-r.getX()), (float)(h/4-r.getY()));
		g.dispose();
		return new ImageIcon(textImage);	
	}
	
	public static Icon getAttentionImage(Icon icon) {
		return getAttentionImage(icon, Color.RED);
	}
	
	public Icon getAttentionImage(Color color) {
		return getAttentionImage(img, color);
	}
	
	public Icon getAttentionImage() {
		return getAttentionImage(img, Color.RED);
	}
	
	private String getPath() {
		return path;
	}
	
    @Override
	public String toString() {
		return this.name() + " (" + getPath() + ")";
	}

}
